home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / dpmigcc5.zip / RSX / SOURCE / PTRACE.C < prev    next >
C/C++ Source or Header  |  1994-12-12  |  4KB  |  164 lines

  1. /*****************************************************************************
  2.  * FILE: ptrace.c                                 *
  3.  *                                         *
  4.  * DESC:                                     *
  5.  *    - ptrace handler                             *
  6.  *                                         *
  7.  * Copyright (C) 1993,1994                             *
  8.  *    Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld             *
  9.  *    email: rainer@mathematik.uni-bielefeld.de                 *
  10.  *                                         *
  11.  *****************************************************************************/
  12.  
  13. #include "DPMI.H"
  14. #include "DPMI10.H"
  15. #include "PROCESS.H"
  16. #include "CDOSX32.H"
  17. #include "START32.H"
  18. #include "ADOSX32.H"
  19. #include "COPY32.H"
  20. #include "PTRACE.H"
  21. #include "DOSERRNO.H"
  22. #include "KDEB.H"
  23.  
  24. #define FLAG_MASK 0x00000dd9L
  25. #define SINGLE_STEP 0x100
  26.  
  27. int do_ptrace(int request, int child_id, DWORD addr, DWORD data, DWORD * ret)
  28. {
  29.     NEWPROCESS *child;
  30.  
  31. #ifdef CONFIG_KDEB
  32.     if (child_id == 1)
  33.     return KDEB_ptrace(request, addr, data, ret);
  34. #endif
  35.  
  36.     if (!(child = find_process(child_id)))
  37.     return EMX_ESRCH;
  38.  
  39.     if (child->pptr != npz || !(child->p_flags & PF_DEBUG))
  40.     return EMX_ESRCH;
  41.  
  42.     if (child->p_status != PS_STOP && child->p_status != PS_START)
  43.     return EMX_ESRCH;
  44.  
  45.     *ret = 0;
  46.  
  47.     switch (request) {
  48.     case PTRACE_TRACEME:
  49.     case PTRACE_SESSION:
  50.     return 0;
  51.  
  52.     case PTRACE_PEEKTEXT:
  53.     case PTRACE_PEEKDATA:
  54.     if (verify_illegal(child, addr, 4))
  55.         return EMX_EIO;
  56.     *ret = read32(child->data32sel, addr);
  57.     return 0;
  58.  
  59.     case PTRACE_POKETEXT:
  60.     case PTRACE_POKEDATA:
  61.     if (verify_illegal(child, addr, 4))
  62.         return EMX_EIO;
  63.     if (dpmi10) {
  64.         WORD page, pageorg;
  65.  
  66.         read32(child->data32sel, addr);    /* page in */
  67.         if (GetPageAttributes(child->memhandle, addr & ~0xFFFL, 1, &pageorg))
  68.         return EMX_EIO;
  69.         pageorg &= ~16;    /* don't modify access/dirty */
  70.         page = pageorg | 8; /* read/write access */
  71.         if (ModifyPageAttributes(child->memhandle, addr & ~0xFFFL, 1, &page))
  72.         return EMX_EIO;
  73.         store32(child->data32sel, addr, data);
  74.         ModifyPageAttributes(child->memhandle, addr & ~0xFFFL, 1, &pageorg);
  75.     } else
  76.         store32(child->data32sel, addr, data);
  77.     *ret = data;
  78.     return 0;
  79.  
  80.     case PTRACE_EXIT:
  81.     /* to do : switch to child -> do_signal(); */
  82.     child->p_flags |= PF_WAIT_WAIT;
  83.     return 0;
  84.  
  85.     case PTRACE_PEEKUSER:
  86.     if (addr == 0x30) {    /* u_ar0  */
  87.         *ret = 0xE0000000 + ((DWORD) (UINT) & (child->regs));
  88.         return 0;
  89.     } else {        /* peek regs */
  90.         DWORD *peekat;
  91.         peekat = (DWORD *) (UINT) (addr);
  92.  
  93.         if (peekat < &(child->regs.gs) || peekat > &(child->regs.ss))
  94.         return EMX_EIO;
  95.  
  96.         *ret = *peekat;
  97.         return 0;
  98.     }
  99.  
  100.     case PTRACE_POKEUSER:
  101.     {
  102.         /* poke regs */
  103.         DWORD *pokeat;
  104.  
  105.         pokeat = (DWORD *) (UINT) addr;
  106.  
  107.         if (pokeat < &(child->regs.gs) || pokeat > &(child->regs.ss))
  108.         return EMX_EIO;
  109.  
  110.         /* change data for critical regs */
  111.         if (pokeat == &(child->regs.eflags)) {
  112.         data &= FLAG_MASK;
  113.         data |= *pokeat & ~FLAG_MASK;
  114.         } else if (pokeat <= &(child->regs.ds)
  115.                || pokeat == &(child->regs.cs))
  116.         data = *pokeat;
  117.         else if (pokeat == &(child->regs.esp)) {
  118.         if (verify_illegal(child, data, 4))
  119.             return EMX_EIO;
  120.         child->regs.esp = data;
  121.         child->regs.esporg = data + 12L;
  122.         } else if (pokeat == &(child->regs.esporg)) {
  123.         if (verify_illegal(child, data, 4))
  124.             return EMX_EIO;
  125.         child->regs.esporg = data;
  126.         child->regs.esp = data - 12L;
  127.         } else if (pokeat == &(child->regs.eip))
  128.         if (verify_illegal(child, data, 4))
  129.             return EMX_EIO;
  130.  
  131.         *pokeat = data;
  132.         *ret = data;
  133.  
  134.         return 0;
  135.     }
  136.  
  137.     case PTRACE_STEP:
  138.     if ((int)data > 0 && (int)data <= MAX_SIGNALS)
  139.         send_signal(child, (WORD) data);
  140.     child->regs.eflags |= SINGLE_STEP;
  141.     if (child->regs.esp == child->regs.esporg)
  142.         child->regs.esp -= 12;
  143.  
  144.     npz->p_status = PS_STOP;
  145.     switch_context(child);
  146.     npz->p_status = PS_RUN;
  147.     return 0;
  148.  
  149.     case PTRACE_RESUME:
  150.     if ((int)data > 0 && (int)data <= MAX_SIGNALS)
  151.         send_signal(child, (int) data);
  152.     if (child->regs.esp == child->regs.esporg)
  153.         child->regs.esp -= 12;
  154.  
  155.     npz->p_status = PS_STOP;
  156.     switch_context(child);
  157.     npz->p_status = PS_RUN;
  158.     return 0;
  159.  
  160.     default:
  161.     return EMX_EIO;
  162.     }
  163. }
  164.